package service

import (
	"gitee.com/molonglove/goboot/gorm"
	"helper-api/app/models/entity"
	"helper-api/app/models/request"
	"helper-api/app/models/response"
	"helper-api/core"
	"time"
)

var Role = new(RoleService)

type RoleService struct{}

// CreateRole 创建角色
func (s *RoleService) CreateRole(param request.RoleCreateRequest) (*response.RoleListResponse, *response.BusinessError) {
	var (
		result *entity.Role
		total  int64
		err    error
	)
	if err = core.DB.Model(&entity.Role{}).
		Where("can_view = 1 and (name = ? or code = ?)", param.Name, param.Code).
		Count(&total).
		Error; err != nil {
		core.Log.Error("执行SQL错误 => %s", err.Error())
		return nil, response.NewBusinessError(response.SqlExecuteError)
	}
	if total > 0 {
		core.Log.Error("查询到相同的数据 => %d条", total)
		return nil, response.NewBusinessError(response.ExistSameData)
	}
	result = &entity.Role{
		Name:       param.Name,
		Brief:      param.Desc,
		Code:       param.Code,
		CreateId:   param.UserId,
		CreateTime: time.Now(),
		CanView:    1,
	}
	if err = core.DB.Model(&entity.Role{}).Create(result).Error; err != nil {
		core.Log.Error("执行SQL错误 => %s", err.Error())
		return nil, response.NewBusinessError(response.RoleCreateError)
	}
	return &response.RoleListResponse{
		Id:         result.Id,
		Name:       result.Name,
		Code:       result.Code,
		Brief:      result.Brief,
		CreateTime: time.Now(),
	}, nil
}

// UpdateRole 更新角色
func (s *RoleService) UpdateRole(param request.RoleUpdateRequest) (*response.RoleListResponse, *response.BusinessError) {
	var (
		isUpdate bool
		result   entity.Role
		rolePerm []entity.RolePermission
		tx       *gorm.DB
		err      error
	)
	tx = core.DB.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	if err = tx.Model(&entity.Role{}).
		Where("id = ? and can_view = 1", param.Id).
		First(&result).
		Error; err != nil {
		core.Log.Error("执行SQL查询错误 => %s", err.Error())
		return nil, response.NewBusinessError(response.SqlExecuteError)
	}
	if result.Name != param.Name {
		result.Name, isUpdate = param.Name, true
	}
	if result.Code != param.Code {
		result.Code, isUpdate = param.Code, true
	}
	if result.Brief != param.Desc {
		result.Brief, isUpdate = param.Desc, true
	}
	if isUpdate {
		result.UpdateId = param.UserId
		result.UpdateTime = time.Now()
		if err = tx.Save(&result).Error; err != nil {
			core.Log.Error("执行SQL更新错误 => %s", err.Error())
			return nil, response.NewBusinessError(response.SqlExecuteError)
		}
	}
	if len(param.PermId) > 0 {
		rolePerm = make([]entity.RolePermission, 0)
		for _, item := range param.PermId {
			rolePerm = append(rolePerm, entity.RolePermission{
				RoleId: result.Id,
				PermId: item,
			})
		}
		if err = tx.Where("role_id = ?", result.Id).Delete(&entity.RolePermission{}).Error; err != nil {
			core.Log.Error("删除旧角色授权错误 => %s", err.Error())
			return nil, response.NewBusinessError(response.SqlExecuteError)
		}
		if err = tx.Create(&rolePerm).Error; err != nil {
			core.Log.Error("保存新角色授权错误 => %s", err.Error())
			return nil, response.NewBusinessError(response.SqlExecuteError)
		}
	}
	return &response.RoleListResponse{
		Id:         result.Id,
		Name:       result.Name,
		Code:       result.Code,
		Brief:      result.Brief,
		CreateTime: result.CreateTime,
	}, nil
}

// DeleteRole 删除角色
func (s *RoleService) DeleteRole(ids []int64, id int64) *response.BusinessError {
	if err := core.DB.Model(&entity.Role{}).
		Where("id in ?", ids).
		Updates(map[string]interface{}{"update_id": id, "update_time": time.Now(), "can_view": 0}).
		Error; err != nil {
		core.Log.Error("执行SQL删除错误 => %s", err.Error())
		return response.NewBusinessError(response.SqlExecuteError)
	}
	return nil
}

// PageRole 角色分页
func (s *RoleService) PageRole(param request.RolePageRequest) (*response.PageData, *response.BusinessError) {
	var (
		err        error
		tx         *gorm.DB
		total      int64
		records    []response.RoleListResponse
		result     *response.PageData
		getRoleIds = func(roles []response.RoleListResponse) []int64 {
			temp := make([]int64, 0)
			for _, item := range roles {
				temp = append(temp, item.Id)
			}
			return temp
		}
		filter = func(list []response.RolePermissionResponse, roleId int64) (data []int64) {
			data = make([]int64, 0)
			for _, item := range list {
				if item.RoleId == roleId {
					data = append(data, item.PermId)
				}
			}
			return
		}
		roleIds   []int64
		rolePerms []response.RolePermissionResponse
	)
	tx = core.DB.Model(&entity.Role{}).Where("can_view = 1")
	if param.Name != "" {
		tx.Where("name = ?", param.Name)
	}
	if err = tx.Count(&total).Error; err != nil {
		core.Log.Error("统计SQL执行错误 => %s", err.Error())
		return result, response.NewBusinessError(response.SqlExecuteError)
	}
	if total != 0 {
		tx = core.DB.Model(&entity.Role{})
		if param.Name != "" {
			tx.Where("name = ?", param.Name)
		}
		if err = tx.Where("can_view = 1").
			Order("create_time").
			Offset(param.Offset()).
			Limit(param.Size).
			Find(&records).
			Error; err != nil {
			core.Log.Error("SQL执行错误 => %s", err.Error())
			return result, response.NewBusinessError(response.SqlExecuteError)
		}
		roleIds = getRoleIds(records)
		if err = core.DB.Model(&entity.RolePermission{}).
			Select("s_role_permission.role_id,s_role_permission.perm_id").
			Where("s_role_permission.role_id in (?)", roleIds).
			Find(&rolePerms).
			Error; err != nil {
			core.Log.Error("获取角色资源数据错误 => %s", err.Error())
			return result, response.NewBusinessError(response.SqlExecuteError)
		}
		for i := 0; i < len(records); i++ {
			records[i].PermIds = filter(rolePerms, records[i].Id)
		}
	}
	result = response.NewPageData(param.Page, param.Size, total, records)
	return result, nil
}

// RoleAll 所有角色
func (s *RoleService) RoleAll() ([]response.RoleKeyValueResponse, *response.BusinessError) {
	var (
		roles []response.RoleKeyValueResponse
		err   error
	)
	if err = core.DB.Debug().
		Model(&entity.Role{}).
		Select("id as value, name as label").
		Where("can_view = 1").
		Find(&roles).
		Error; err != nil {
		return nil, response.NewBusinessError(response.DataNotExist)
	}
	return roles, nil
}
